tblNearbyPlayers = {}
function Gather_Nearby_Players()
	-- Clear the table of previous results
	tblNearbyPlayers = {}
	local vGroupSize = GetNumGroupMembers()
	local vGroupType = nil
	-- Determine if we are in a raid or party
	if IsInRaid() then vGroupType = "raid" else vGroupType = "party" end
	-- See who is within range of the player, and is able to be healed
	for i = 0, vGroupSize do
		-- Create the group member id, eg raid5
		local vPlayerID = vGroupType .. tostring(i)
		-- Include the player also
		if i == 0 then vPlayerID = "player" end
		-- Create a FireHack object from the group member
		local obj = GetObjectFromUnitID(vPlayerID)
		if obj
		and obj:Exists()
		and obj:GetDistance(Player) <= 44
		and obj:InLineOfSight()
		and UnitExists(vPlayerID) == 1 
		and UnitIsDeadOrGhost(vPlayerID) ~= 1
		and UnitIsConnected(vPlayerID) == 1
		and UnitIsFriend("player", vPlayerID) == 1
		and UnitControllingVehicle(vPlayerID) == false
		then
			table.insert(tblNearbyPlayers, vPlayerID)
		end
	end
end

function Find_Lowest_HP()
	if # tblNearbyPlayers > 0 then
		local vLowestHealth = 101
		local vLowestID = "player"
		local vTempHealth = nil
		local vTempID = nil
		for i = 0, # tblNearbyPlayers do
			vTempID = tblNearbyPlayers[i]
			if vTempID ~= nil then
				-- Find the nearby players health
				local vTempHealth = ((UnitHealth(vTempID) / UnitHealthMax(vTempID)) * 100)
				-- Player's health is lower than what we currently have
				if vTempHealth < vLowestHealth then
					-- Update to reduce to whoever has the least health
					vLowestHealth = vTempHealth
					vLowestID = vTempID
				end
			end
		end
		-- Return the details for the rotation
		if vLowestID ~= nil and vLowestHealth ~= nil then
			return vLowestID, vLowestHealth
		end
	end
end

tblGroupedPlayersHealth = {}
function GroupedPlayersHealth(sourceUnit,dist,health)
	--[[
		sourceUnit = raidX/partyX
		dist = yards
		health = health percentage or lower
		eg. GroupedPlayersHealth("raid5", 40, 50)
	]]
	local vPlayerNearCount = 0
	tblGroupedPlayersHealth = {}
	for i=1,GetTotalObjects(4) do
		local guid = IGetObjectListEntry(i);
		ISetAsUnitID(guid,"intPlayer");		
		if UnitExists("intPlayer") == 1 
		and UnitIsDeadOrGhost("intPlayer") ~= 1
		and UnitIsConnected("intPlayer") == 1
		and UnitIsFriend("player", "intPlayer") == 1
		and UnitControllingVehicle("intPlayer") == false
		and UnitCreatureType("intPlayer") ~= "Totem"
		and UnitCreatureType("intPlayer") ~= "Non-combat Pet"
		and UnitCreatureType("intPlayer") ~= "Critter"
		and UnitCreatureType("intPlayer") ~= "Gas Cloud"
		and UnitCreatureType("intPlayer") ~= "Mechanical"
		and UnitIsPlayer("intPlayer") == 1
		then
			if _distance("intPlayer", sourceUnit) <= dist
			and ((UnitHealth("intPlayer") / UnitHealthMax("intPlayer")) * 100) <= health
			then
				local vObj = GetObjectFromGUID(guid)
				if vObj
				and vObj:Exists()
				then
					table.insert(tblGroupedPlayersHealth, vObj)
				end
				vPlayerNearCount = vPlayerNearCount + 1
			end
			ClearUnitID("intPlayer"); 
		end
	end
	return vPlayerNearCount
end

tblGroupedNPCHealth = {}
function GroupedNPCHealth(sourceUnit,dist,health)
	local vNPCNearCount = 0
	tblGroupedNPCHealth = {}
	for i=1,GetTotalObjects(3) do
		local guid = IGetObjectListEntry(i);
		ISetAsUnitID(guid,"intPlayer");		
		if UnitExists("intPlayer") == 1 
		and UnitIsFriend("player", "intPlayer") == nil
		and UnitCreatureType("intPlayer") ~= "Totem"
		and UnitCreatureType("intPlayer") ~= "Non-combat Pet"
		and UnitCreatureType("intPlayer") ~= "Critter"
		and UnitCreatureType("intPlayer") ~= "Gas Cloud"
		and UnitCreatureType("intPlayer") ~= "Mechanical"
		and UnitCreatureType("intPlayer") == "Humanoid"
		and UnitIsPlayer("intPlayer") == nil
		then
			if _distance("intPlayer", sourceUnit) <= dist
			and ((UnitHealth("intPlayer") / UnitHealthMax("intPlayer")) * 100) <= health
			then
				local vObj = GetObjectFromGUID(guid)
				if vObj
				and vObj:Exists()
				then
					table.insert(tblGroupedNPCHealth , vObj)
				end
				vNPCNearCount = vNPCNearCount + 1
			end
			ClearUnitID("intPlayer"); 
		end
	end
	return vNPCNearCount 
end

function _distance(unit, sourceUnit)
	if not sourceUnit then sourceUnit = "player"; end
	if UnitExists(unit) and UnitExists(sourceUnit) then
		local X1,Y1,Z1 = IGetLocation(UnitGUID(unit));
		local X2,Y2,Z2 = IGetLocation(UnitGUID(sourceUnit));
		return math.sqrt(((X2-X1)^2)+((Y2-Y1)^2)+((Z2-Z1)^2));
	else 
	return 99999;
	end
end

function IsInSight(Unit)
	if GetObjectFromUnitID("player"):InLineOfSight(GetObjectFromUnitID(Unit)) then
		return true
	else
		return false
	end	
end

function NotEnoughMana(spell)
	local isUsable, notEnoughMana = IsUsableSpell(spell)	
	if notEnoughMana == 1 then
		return true
	else
		return false
	end
end

function ccrFindDebuffInGroup(debuff)
	local vGroupSize = GetNumGroupMembers()
	local vGroupType = nil
	if IsInRaid() then vGroupType = "raid" else vGroupType = "party" end
	for i = 0, vGroupSize do
		local vPlayerID = vGroupType .. i
		if i == 0 then vPlayerID = "player" end
		if ccrUnitHasDebuff(vPlayerID, debuff, true) then
			return vPlayerID
		end
	end
end